package com.yd.cfckc.task;

import com.yd.cfckc.util.*;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author cuiyufeng
 * @email cuiyufeng1458@yundasys.com
 * @date 2020/10/16 3:35 下午
 */
public class QlDataTask extends TimerTask {
    private static Logger logger = Logger.getLogger(QlDataTask.class);
    private static boolean isRunning = true;
    private static Long batchTime = 0L;
    private static JedisPool pool = RedisPool.getPool();
    private static Jedis jedis = pool.getResource();
    private static SimpleDateFormat tf = new SimpleDateFormat("yyyyMMdd");
    private static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
    private static String date = initDate();
    private static int count=0;

    private static String initDate(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -3);
        System.out.println("date = " + tf.format(calendar.getTime()));
        return tf.format(calendar.getTime());
    }
    @Override
    public void run() {
        if (isRunning) {
            try {
                count=0;
                long startTime = System.currentTimeMillis();
                Map<String,String> map = jedis.hgetAll(date);
                dateFormat = new SimpleDateFormat("yyyyMMdd");
                Date nowDate = dateFormat.parse(date);
                logger.info("本次更新批次号:"+nowDate);
                long paramTime = nowDate.getTime();
                String yesterday = tf.format(nowDate.getTime()-24*60*60*1000);
                String terday = tf.format(nowDate.getTime());
                String tomorrow = tf.format(nowDate.getTime()+24*60*60*1000);
                if (map.isEmpty()) {
                    logger.info("由于批次号:"+nowDate+" 此次初始化,先全量更新上个批次避免数据遗漏");
                    dealData(yesterday);
                    jedis.hset(date,"yd","1");
                    jedis.expire(date, 864000);
                }else{
                    dealData(date);
                    if(paramTime==batchTime){
                        date =terday;
                    }else{
                        date=tomorrow;
                    }
                }
                long endTime = System.currentTimeMillis();
                logger.info("共解析:"+count+"个csv文件");
                logger.info("本次耗时:"+(endTime-startTime)+" ms");
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
            }
        } else {
            logger.error("QlData 执行异常...");
        }
    }

    public static void dealData(String date) throws ConnectException, Exception {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("-----------------本次更新时间:"+df.format(new Date())+"----------------");
        String responstMsg = PostSendTool.sendMessage(SrvUtil.getProperties()
                .getProperty("request"), getQlxml(date));
        String[] str = XmlAnalysis.getTagAllValue(responstMsg, "d");
        String addrHead = str[0];
        logger.info("下载地址头:"+addrHead);
        if (str.length==4 && !str[0].equals("") && !str[0].equals("null") && !str[1].equals("")&& !str[2].equals("")) {
            dateFormat = new SimpleDateFormat("yyyyMMdd");
            Date batchDate = dateFormat.parse(str[1]);
            logger.info("最新批次号:"+batchDate);
            batchTime = batchDate.getTime();
            jedis.set("cf_sjdw_datas_time",str[2]);
            String addrName = str[3];
            insIterm(addrName,date);
            Map<String,String> map = jedis.hgetAll(date);
            checkIterm(map,addrHead,date);
        }else{
            System.out.println("返回报文中信息不全...");
        }
    }

    public static void insIterm(String addrName,String date){
        String[] addr = addrName.split(";");
        for (int i = 0; i < addr.length; i++) {
            if(!jedis.hexists(date, addr[i])){
                jedis.hset(date, addr[i],"0");
                jedis.expire(date, 864000);
            }
        }
    }

    public static void checkIterm(Map<String,String> map,String urlHead,String date){
        for (Map.Entry<String, String> inte : map.entrySet()) {
            if(inte.getValue().equals("0")){
                if(downLoadDealCsv(urlHead,date,inte.getKey(),"GET")){
                    jedis.hset(date,inte.getKey(),"1");
                }
            }
        }
    }

    public static String getQlxml(String currentDate) {
        StringBuffer xmlData = new StringBuffer();
        xmlData.append(" <req op=\"getcfaddr\">")
                .append("<h>")
                .append("<ver>2.0</ver>")
                .append("<company>"
                        + SrvUtil.getProperties().getProperty("compCode")
                        + "</company>").append("<user>1001</user>")
                .append("<pass>223ef7022e83f6b3c5c3dd2a5a0c7266</pass>")
                .append("<param>"+currentDate+"</param>")
                //.append("<param>20171028</param>")
                .append("</h>").append("</req>");
        return xmlData.toString();
    }

    public static boolean downLoadDealCsv(String url,String date,String fileName, String method) {
        boolean flag = false;
        String path = "/u02/data/cfCheckCache";
        String filePath = path+ File.separator+fileName;
        File file = new File(path);
        String downLoadUrl = url+date+"/"+ SrvUtil.getProperties().getProperty("compCode")+"/"+fileName+".csv";
        System.out.println("qldownLoadUrl = " + downLoadUrl);
        if (!file.exists()) {
            file.mkdirs();
        }
        FileOutputStream fileOut = null;
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        try {
            URL httpUrl = new URL(downLoadUrl);
            conn = (HttpURLConnection) httpUrl.openConnection();
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.connect();
            inputStream = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            fileOut = new FileOutputStream(filePath);
            BufferedOutputStream bos = new BufferedOutputStream(fileOut);

            byte[] buf = new byte[4096];
            int length = bis.read(buf);

            while (length != -1) {
                bos.write(buf, 0, length);
                length = bis.read(buf);
            }
            bos.close();
            bis.close();
            conn.disconnect();
            readCsv(filePath);
            flag = true;
        } catch (Exception e) {
            flag = false;
            logger.error("请求-下载-处理总部数据出现异常!");
            logger.error(e.getMessage(),e);
        }
        return flag;
    }

    public static void readCsv(String filePath) throws IOException {
        CsvReader reader = null;
        Map<String, String> mapTemp = new HashMap<String, String>();
        reader = new CsvReader(filePath, ',', Charset.forName("UTF-8"));
        while (reader.readRecord()) {
            String[] dataArray = reader.getValues();
            if ((dataArray != null) && (dataArray.length >= 2)) {
                mapTemp.put(dataArray[0], dataArray[1]);
            }
        }
        logger.info("已解析:"+filePath);
        count++;
        reader.close();
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        for (Map.Entry<String, String> entry : mapTemp.entrySet()) {
            jedis.setex(entry.getKey(), 864000,entry.getValue());
        }
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     *
     * @param strDate
     * @return
     */
    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }
}
